/** 三国志2连发版,假设全是连发,按键1,2,3是连发a,b,ab宏
  目的是适应游聚的全部连发
  
  By setycyas @2025-04-04
*/

/* 全局设定
*/
#Warn
#MaxThreadsPerHotkey 1
SetWorkingDir(A_ScriptDir)
;导入自定义函数库
#Include "..\Class\OrderMap.2.ahk"
#Include "..\Class\MyFuns.2.ahk"
;导入宏相关函数和UI
#Include "..\Class\FaceDetector.2.ahk"
#Include "..\Class\CommonMacro.2.ahk"
#Include "..\Class\CommonUI.2.ahk"
#Include "..\Class\MyEmu.2.ahk"

SendMode("Input")

/* 制作三国志2的宏类
*/
class WofMacro extends CommonMacro {

  pressDuration := 30 ;重要,因是连发
  horseDelay := 50 ;马上挑人延时,75对关赵都有效,张飞125,魏延赵云50
  backjumpDelay := 50 ;后跳踢延时,关羽30,其他人50

  /* 宏函数
  */

  _下上A(key){
    MyFuns.press("down", 70)
    sleep(30)
    MyFuns.pressKeys(["up", this._keys[1]], [50, 50])
  }
  _下前上A(key){
    local face := this._face.face()
    MyFuns.inputSkill(["down", face, "up", this._keys[1]], [90, 50, 80, 50])
  }
  _左右A(key){
    MyFuns.press("left", 100)
    sleep(30)
    MyFuns.pressKeys(["right", this._keys[1]], [50, 50])
  }
  _右左A(key){
    MyFuns.press("right", 100)
    sleep(30)
    MyFuns.pressKeys(["left", this._keys[1]], [50, 50])
  }
  ;取消了踢
  _后跳踢(key){
    local back := this._face.back()
    ;MyFuns.pressKeys([this._keys[2], back], [50, 70])
    MyFuns.pressKeys([this._keys[2], back], [this.backjumpDelay, 50])
    sleep(50)
    ;this._press(1)
  }
  _下B(key){
    MyFuns.pressKeys(["down", this._keys[2]], [50, 70])
  }
  _下B连发(key){
    local vk := GetKeyVK(MyFuns.getHotkey(key))
    MyFuns.keyDown("down")
    sleep(20)
    this._press(2)
    sleep(20)
    ;已放开键则终止
    if (not MyFuns.getVkState(vk)) {
      MyFuns.keyUp("down")
      return
    }
    ;否则开始连发B结束时再放开下键
    this._连发B(key)
    MyFuns.keyUp("down")
  }
  _吃包子(key){
    static delays := [20, 20, 20, 20, 20, 20]
    local thisKey := MyFuns.getHotkey(key) ;触发技能的热键
    local keys := ["up", "right", this._keys[1], "down", "left", this._keys[1]]
    while (MyFuns.getKeyState(thisKey)) {
      MyFuns.inputSkill(keys, delays)
    }
    /*
    loop {
      MyFuns.inputSkill(keys, delays)
    } until (MyFuns.waitKeyUp(thisKey, 15))
    */
  }
  _骑马左上挑人(key){
    this._马上挑人("up", "left")
  }
  _骑马左下挑人(key){
    this._马上挑人("down", "left")
  }
  _骑马右下挑人(key){
    this._马上挑人("down", "right")
  }
  _骑马右上挑人(key){
    this._马上挑人("up", "right")
  }
  
  _单发键(key, i){
    local vk := GetKeyVK(MyFuns.getHotkey(key))
    this._down(i)
    sleep(30)
    this._up(i)
    while(MyFuns.getVkState(vk)){
      sleep(20)
    }
  }
  _单发拳(key){
    this._单发键(key, 1)
  }
  _单发跳(key){
    this._单发键(key, 2)
  }
  
  _黄忠下B升龙连击(key){
    MyFuns.keyDown("down")
    sleep(40)
    this._press(2)
    sleep(200)
    MyFuns.keyUp("down")
    sleep(40)
    MyFuns.pressKeys(["up", this._keys[1]], [50, 70])
  }
  
  _黄忠下B接连发A(key){
    MyFuns.keyDown("down")
    sleep(40)
    this._press(2)
    sleep(40)
    MyFuns.keyUp("down")
    this._连发A(key)
  }
  
  _赵云下B升龙连击(key){
    MyFuns.keyDown("down")
    sleep(40)
    this._press(2)
    sleep(200)
    MyFuns.keyUp("down")
    sleep(40)
    local face := this._face.face()
    MyFuns.inputSkill([face, "up", this._keys[1]], [50, 80, 50])
  }

  ;改装的连发
  _连发(key, i){
    local vk := GetKeyVK(MyFuns.getHotkey(key))
    if (not MyFuns.getVkState(vk)) {
      return
    }
    this._down(i)
    while (MyFuns.getVkState(vk)) {
      sleep(20)
    }
    this._up(i)
  }
  _连发A(key){
    this._连发(key, 1)
  }
  _连发B(key){
    this._连发(key, 2)
  }

  ;** 不直接绑定到热键的操作
  ;uod为up或down,lor为left或right,都是马上挑人的参数
  _马上挑人(uod, lor){
    MyFuns.pressKeys([uod, this._keys[1]], [50, 70])
    sleep(this.horseDelay)
    MyFuns.press(lor, 70)
  }

  /* 重载宏接口
  */
  _setMacro(){
    local obm := ObjBindMethod ;函数名简写,制作对象绑定函数
    ;制作宏相关Map
    this.macroMap := OrderMap()
    this.macroMap["连发A"] := obm(this, "_连发A")
    this.macroMap["连发B"] := obm(this, "_连发B")
    ;this.macroMap["连发AB"] := obm(this, "_连发C")
    this.macroMap["下上A"] := obm(this, "_下上A")
    this.macroMap["下前上A"] := obm(this, "_下前上A")
    this.macroMap["后跳踢"] := obm(this, "_后跳踢")
    this.macroMap["下B"] := obm(this, "_下B")
    this.macroMap["下B连发"] := obm(this, "_下B连发")
    this.macroMap["吃包子"] := obm(this, "_吃包子")
    this.macroMap["骑马左上挑人"] := obm(this, "_骑马左上挑人")
    this.macroMap["骑马左下挑人"] := obm(this, "_骑马左下挑人")
    this.macroMap["骑马右上挑人"] := obm(this, "_骑马右上挑人")
    this.macroMap["骑马右下挑人"] := obm(this, "_骑马右下挑人")
    this.macroMap["左右A"] := obm(this, "_左右A")
    this.macroMap["右左A"] := obm(this, "_右左A")
    this.macroMap["单发拳"] := obm(this, "_单发拳")
    this.macroMap["单发跳"] := obm(this, "_单发跳")
    this.macroMap["黄忠下B升龙连击"] := obm(this, "_黄忠下B升龙连击")
    this.macroMap["黄忠下B接连发A"] := obm(this, "_黄忠下B接连发A")
    this.macroMap["赵云下B升龙连击"] := obm(this, "_赵云下B升龙连击")
    ;制作指定宏顺序的数组
    this.macroArr := this.macroMap.getKeys()
  }

}

/* 制作三国志2专用UI
*/
class WofUI extends CommonUI {

  DEFAULT_HOTKEYS := "w,s,q,2,3,r"
  ;EXE_ARRAY := [MyEmu.WINKAWAKS, MyEmu.FBAS, MyEmu.XZONE ,My]
  _hoseDelayEdit := "" ;记录骑马挑人延时的文本框,测试发现:魏延赵云50,关羽100,张飞150
  _lastPreset := "" ;上一个读入的预设

  /* 构造函数
  */
  __New(macro){
    super.__New("三国志2连发版", macro)
    this._preset := Map(
      "关张魏步行", ["下上A", "后跳踢", "吃包子", 
        "下B连发", "单发拳", "单发跳"],
      "关张魏骑马", ["骑马左下挑人", "骑马左上挑人", "骑马右上挑人", 
        "骑马右下挑人", "单发拳", "单发跳"],
      "赵云步行", ["下前上A", "后跳踢", "赵云下B升龙连击", 
        "下B连发", "下上A", "单发跳"], 
      "赵云骑马", ["骑马左下挑人", "骑马左上挑人", "骑马右上挑人", 
        "骑马右下挑人", "单发拳", "单发跳"],
      "黄忠步行", ["下上A", "后跳踢", "黄忠下B接连发A", 
        "下B连发", "黄忠下B升龙连击", "单发跳"], 
      "黄忠骑马", ["右左A", "单发拳", "单发拳",  
        "左右A", "连发B", "单发跳"])
  }

  /* 重写接口
  */
  ;自定义gui组件标签页,增加一个骑马挑人延时
  _customGui(){
    super._customGui()
    this._myGui.Add("Text", "w100", "骑马挑人延时:")
    this._horseDelayEdit := this._myGui.Add("Edit", "w100", 
      this._macro.horseDelay)
      this._myGui.Add("Text", "w100", "后跳踢延时:")
    this._backjumpDelayEdit := this._myGui.Add("Edit", "w100", 
      this._macro.backjumpDelay)
  }
  ;提交数据后更新起马挑人延时和后跳踢延时
  ;首次提交数据时绑定RCtrl键为预设转换热键
  _onSubmitEnd(){
    super._onSubmitEnd()
    this._macro.horseDelay := this._horseDelayEdit.Text
    this._macro.backjumpDelay := this._backjumpDelayEdit.Text
    if (this._submitTimes == 0){
      HotIfWinActive(this._winTitle)
      Hotkey("RCtrl", this._changePreset.bind(this))
      HotIfWinActive()
    }
  }

  /* 重写setup,更改可选的exe,读入预设
  */
  setup(){
    super.setup()
    this._myGui.opt("+AlwaysOnTop")
    this._myGui.show("x1100 y330")
    this.readPresetMenu("关张魏步行")
  }

  /* 重写读入预设函数,增加状态栏提示
  */
  readPresetMenu(itemName, itemPos := "", _menu := ""){
    super.readPresetMenu(itemName, itemPos, _menu)
    this._lastPreset := itemName
  }

  /* 预设转换函数,读入预设并无提示提交
  */
  _changePreset(key){
    local newPreset := "关张魏步行"
    if (this._lastPreset == "关张魏步行") {
      newPreset := "关张魏骑马"
    }
    if (this._lastPreset == "关张魏骑马") {
      newPreset := "关张魏步行"
    }
    if (this._lastPreset == "赵云步行") {
      newPreset := "赵云骑马"
      this._horseDelayEdit.Text := 70
    }
    if (this._lastPreset == "赵云骑马") {
      newPreset := "赵云步行"
    }
    if (this._lastPreset == "黄忠步行") {
      newPreset := "黄忠骑马"
    }
    if (this._lastPreset == "黄忠骑马") {
      newPreset := "黄忠步行"
    }
    this.readPresetMenu(newPreset)
    this.submit()
    this._statusBar.SetText(newPreset)
  }

}

/* 运行当前脚本
*/
if (A_ScriptName == "三国志2连发版.2.ahk"){
  face := FaceDetector() ;方向检测对象
  macro := WofMacro(face, ["q","d","r"]) ;宏对象,有界面时第二个参数可以随便写但长度不要小于2
  ;新建界面并设定
  ui := WofUI(macro)
  ui.setup()
  ;ui._exeComboBox.Choose(MyEmu.WINKAWAKS)
  ui._exeComboBox.Choose(MyEmu.MAME)
  ui._gameKeyEdit.Text := "s,c,space"
  ui._hotkeyEdit.Text := "~a,~w,~e,~f,~x,~d"
  ui._fpsEdit.Text := 14
  ui.readPresetMenu("关张魏步行")
}